package org.breathe.aof;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.breathe.aof.loader.AofLoader;
import org.breathe.aof.writer.AofBatchWriter;
import org.breathe.aof.writer.Writer;
import org.breathe.aof.writer.impl.AofWriter;
import org.breathe.protocal.decode.RespArray;
import org.breathe.server.core.RedisCore;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author: breathe
 * @createTime: 2025-05-16
 */
public class AofManager {
    private AofBatchWriter aofBatchWriter;
    private Writer writer;
    private String fileName;
    private boolean fileExists;
    private AofLoader aofLoader;
    private RedisCore redisCore;
    private static final int DEFAULT_FLUSH_INTERVAL_MS = 1000;
    private static final boolean DEFAULT_PREALLOCATE = true;
    public AofManager(String fileName, RedisCore redisCore) throws Exception {
        this(fileName, new File(fileName).exists(), DEFAULT_PREALLOCATE, DEFAULT_FLUSH_INTERVAL_MS, redisCore);
    }
    public AofManager(String fileName, boolean fileExists, boolean preAllocated, int flushInterval, RedisCore redisCore) throws Exception {
        this.fileName = fileName;
        this.fileExists = fileExists;
        this.writer = new AofWriter(new File(fileName), preAllocated, flushInterval, null);
        this.aofBatchWriter = new AofBatchWriter(writer, flushInterval);
        this.redisCore = redisCore;
        this.aofLoader = new AofLoader(fileName, redisCore);
    }
    public void load() {
        aofLoader.load();
    }
    public void append(RespArray respArray) throws IOException {
        ByteBuf byteBuf = Unpooled.buffer();
        respArray.encode(respArray, byteBuf);
        aofBatchWriter.write(byteBuf);
    }
    public void close() throws IOException {
        if (aofBatchWriter != null) {
            aofBatchWriter.close();
        }
        if (writer != null) {
            writer.close();
        }
        if (aofLoader != null) {
            aofLoader.close();
        }
    }
    public void flush() throws Exception {
        if(aofBatchWriter != null){
            aofBatchWriter.flush();
        }
    }
}
